package com.cjh.common;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.cjh.common.dto.PageParamDto;
import com.cjh.common.util.ApprenticeUtil;
import com.cjh.common.util.ResponseUtils;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.*;

/** 核心公共controller类
 */
public class BaseController<S extends IService<E>, E> {

    @Autowired
    protected S baseService;

    @ApiOperation("增")
    @PostMapping("/insert")
    public ResponseUtils insert(@RequestBody E entity) {
        baseService.save(entity);
        return ResponseUtils.success("添加成功");
    }

    @ApiOperation("删")
    @PostMapping("/deleteById")
    public ResponseUtils delete(@RequestBody List<Integer> ids) {

        baseService.removeByIds(ids);
        return ResponseUtils.success("添加成功");
    }

    @ApiOperation("改")
    @PostMapping("/updateById")
    public ResponseUtils updateById(@RequestBody E entity) {
        baseService.updateById(entity);
        return ResponseUtils.success("添加成功");
    }

    @ApiOperation("查")
    @GetMapping("/getById")
    public ResponseUtils getById(@RequestParam Integer id) {
        return ResponseUtils.success(baseService.getById(id));
    }

    @ApiOperation("存")
    @PostMapping("/save")
    public ResponseUtils save(@RequestBody E entity) {
        baseService.saveOrUpdate(entity);
        return ResponseUtils.success("添加成功");
    }

    @ApiOperation("list查")
    @PostMapping("/list")
    public ResponseUtils list(@RequestBody E entity) {
        QueryWrapper<E> queryWrapper = ApprenticeUtil.getQueryWrapper(entity);
        List<E> list = baseService.list(queryWrapper);
        return ResponseUtils.success(list);
    }

    @ApiOperation("list复杂查询")
    @PostMapping("/list_mult")
    public ResponseUtils listMult(@RequestBody Object queryInfo) {
        QueryWrapper<E> queryWrapper = new QueryWrapper<>();
        queryWrapApply(queryWrapper,queryInfo);
        List<E> list = baseService.list(queryWrapper);
        return ResponseUtils.success(list);
    }

    @ApiOperation("page查")
    @PostMapping("/page")
    public ResponseUtils page(@RequestBody PageParamDto<E> pageParamDto) {
        //限制条件
        if (pageParamDto.getPage() < 1) {
            pageParamDto.setPage(1);
        }

        if (pageParamDto.getSize() > 100) {
            pageParamDto.setSize(100);
        }
        Page<E> page = new Page<>(pageParamDto.getPage(), pageParamDto.getSize());
        QueryWrapper<E> queryWrapper = new QueryWrapper<>();
        //升序
        String asc = pageParamDto.getAsc();
        if (!StrUtil.isEmpty(asc) && !"null".equals(asc)) {
            String[] split = asc.split(",");
            queryWrapper.orderByAsc(Arrays.asList(split));
        }

        //降序
        String desc = pageParamDto.getDesc();
        if (!StrUtil.isEmpty(desc) && !"null".equals(desc)) {
            String[] split = desc.split(",");
            queryWrapper.orderByAsc(Arrays.asList(split));
        }
        //复杂条件查询在这里
        if(pageParamDto.getQuery_info()!=null){
            queryWrapApply(queryWrapper,pageParamDto.getQuery_info());
        }
        Page<E> ePage = baseService.page(page, queryWrapper);
        return ResponseUtils.success(ePage);
    }

    public   ResponseUtils page(PageParamDto<E> pageParamDto,QueryWrapper<E> queryWrapper) {
        //限制条件
        if (pageParamDto.getPage() < 1) {
            pageParamDto.setPage(1);
        }

        if (pageParamDto.getSize() > 100) {
            pageParamDto.setSize(100);
        }
        Page<E> page = new Page<>(pageParamDto.getPage(), pageParamDto.getSize());
//        QueryWrapper<E> queryWrapper = new QueryWrapper<>();
        //升序
        String asc = pageParamDto.getAsc();
        if (!StrUtil.isEmpty(asc) && !"null".equals(asc)) {
            String[] split = asc.split(",");
            queryWrapper.orderByAsc(Arrays.asList(split));
        }

        //降序
        String desc = pageParamDto.getDesc();
        if (!StrUtil.isEmpty(desc) && !"null".equals(desc)) {
            String[] split = desc.split(",");
            queryWrapper.orderByAsc(Arrays.asList(split));
        }
        Page<E> ePage = baseService.page(page, queryWrapper);
        return ResponseUtils.success(ePage);
    }

    @ApiOperation("获取数量")
    @PostMapping("/count")
    public ResponseUtils count(@RequestBody E entity) {
        QueryWrapper<E> queryWrapper = ApprenticeUtil.getQueryWrapper(entity);
        long count = baseService.count(queryWrapper);
        return ResponseUtils.success(count);
    }
    @ApiOperation("获取复杂条件数量")
    @PostMapping("/count_mult")
    public ResponseUtils count_mult(@RequestBody Object queryInfo) {
        QueryWrapper<E> queryWrapper = new QueryWrapper<>();
        queryWrapApply(queryWrapper,queryInfo);
        long count = baseService.count(queryWrapper);
        return ResponseUtils.success(count);
    }

    /**
     * where base条件直接输入，这样更加灵活
     * @param queryWrapper
     * @param queryInfo {"apply_sql":"name={0},id>{1}","objs":[]}
     */
    public static void queryWrapApply(QueryWrapper queryWrapper,Object queryInfo){
        JSONObject jsonObject = new JSONObject(queryInfo);
        String sql = jsonObject.getStr("apply_sql");
        JSONArray sqlObjs = jsonObject.getJSONArray("objs");
        Object[] objects=new Object[sqlObjs.size()];
        for (int i = 0; i < sqlObjs.size(); i++) {
            Object obj = sqlObjs.getObj(i);
            objects[i]=obj;
        }
        queryWrapper.apply(sql,objects);
    }

    /**
     * 构造防止sql注入的QueryWrapper
     * @param wrapper
     * @param sql
     * @param queryInfo {0_name1:xxxx,1_name2:dddd}
     */
    public static void  applyQueryWrapper(QueryWrapper wrapper,String sql,Object queryInfo){
        wrapper.apply(sql,getParamObjs(queryInfo));
    }

    /**
     * 按照约定 字段名为 0_xxx 约定输入，防止sql注入
     * @param queryInfo
     * @return
     */
    public static Object[] getParamObjs(Object queryInfo){
        JSONObject jsonObject = new JSONObject(queryInfo);
        Set<String> names = jsonObject.keySet();
        Object[] objs=new Object[names.size()];
        Map<Integer,Object> codeMap=new HashMap<>();
        for (String name : names) {
            String codeStr = name.split("_")[0];
            codeMap.put(Integer.parseInt(codeStr),jsonObject.get(name));
        }
        for (int i = 0; i < objs.length; i++) {
            objs[i]=codeMap.get(i);
        }
        return objs;
    }
}